import yaml
from os import path
import json
import re
from templement import *
import copy
class AutoUpdateMqtt:
    def __init__(self) -> None:
        # self.sourcefile = path.join("configuration.yaml")
        # self.targetfile = path.join("mqtt.json")
        # 当前目录
        self.sourcefile = path.join( path.dirname(__file__),"configuration.yaml")
        self.targetfile = path.join( path.dirname(__file__),"mqtttemp.json")
        print(self.sourcefile)
        self.mappings = []
        self._rpc = {"serverSideRpc": []}
        self.names = []
        self.load_config()
        pass

    def load_config(self):
        with open(self.sourcefile, "r", encoding='utf-8') as f:
            self.config = yaml.safe_load(f)
        with open(self.targetfile, "r", encoding='utf-8') as f:
            self.mqtt = json.load(f)

    def creat_temprature_mapping(self):
        self._temprature = {}
        for temprature in self.config["devices"].values():
            if temprature.get("friendly_name").split("/")[0] not in self._temprature:
                self._temprature[temprature.get("friendly_name").split("/")[0]] = []
            self._temprature[temprature.get("friendly_name").split("/")[0]].append(temprature.get("friendly_name"))
        temprature_template = ZIGBEE2MQTT_TEMPERATURE_MAPPING
        temprature_template["converter"]["deviceTypeJsonExpression"] = TEMPERATURE_TYPE
        temprature_template["converter"]["deviceLabelJsonExpression"] = SENSOR_LABEL
        for temprature in self._temprature:
            if temprature == "单路开关" or temprature == "双路开关" or temprature == "三路开关":
                # 深拷贝取模板
                temprature_double_mapping = copy.deepcopy(temprature_template)
                temprature_double_mapping["topicFilter"] = temprature_template["topicFilter"] + temprature + "/+"
                temprature_double_mapping["converter"]["timeseries"][0]["value"] = "${" + TEMPERATURE + "}"
                temprature_double_mapping["converter"]["deviceNameTopicExpression"] = TEMPERATURE_GET
                self.mappings.append(temprature_double_mapping)
            else:
                pass

    def creat_switch_mapping(self):
        self._switch = {}
        for switch in self.config["devices"].values():
            if switch.get("friendly_name").split("/")[0] not in self._switch:
                self._switch[switch.get("friendly_name").split("/")[0]] = []
            self._switch[switch.get("friendly_name").split("/")[0]].append(switch.get("friendly_name"))
        switch_template = ZIGBEE2MQTT_SWITCH_MAPPING
        switch_template["converter"]["deviceTypeJsonExpression"] = LIGHTING_SWITCH
        switch_template["converter"]["deviceLabelJsonExpression"] = ENERGY_CONSUMING_EQUIPMENT
        switch_mappings = []
        for switch in self._switch:
            if switch == "单路开关":
                # 深拷贝取模板
                switch_double_mapping_left = copy.deepcopy(switch_template)
                switch_double_mapping_left["topicFilter"] = switch_template["topicFilter"] + switch + "/+"
                switch_double_mapping_left["converter"]["timeseries"][0]["value"] = "${" + STATE + "}"
                switch_double_mapping_left["converter"]["deviceNameTopicExpression"] = SWITCHLEFT
                switch_mappings.append(switch_double_mapping_left)

            elif switch == "双路开关":
                # 取新模板
                switch_double_mapping_left = copy.deepcopy(switch_template)
                switch_double_mapping_left["topicFilter"] = switch_template["topicFilter"] + switch + "/+"
                switch_double_mapping_left["converter"]["timeseries"][0]["value"] = "${" + STATE_LEFT + "}"
                switch_double_mapping_left["converter"]["deviceNameTopicExpression"] = SWITCHLEFT
                switch_mappings.append(switch_double_mapping_left)
                switch_double_mapping_right = copy.deepcopy(switch_template)
                switch_double_mapping_right["topicFilter"] = switch_template["topicFilter"] + switch + "/+"
                switch_double_mapping_right["converter"]["timeseries"][0]["value"] = "${" + STATE_RIGHT + "}"
                switch_double_mapping_right["converter"]["deviceNameTopicExpression"] = SWITCHRIGHT
                switch_mappings.append(switch_double_mapping_right)
            elif switch == "三路开关":
                # 取新模板
                switch_triple_mapping_left = copy.deepcopy(switch_template)
                switch_triple_mapping_left["topicFilter"] = switch_template["topicFilter"] + switch + "/+"
                switch_triple_mapping_left["converter"]["timeseries"][0]["value"] = "${" + STATE_LEFT + "}"
                switch_triple_mapping_left["converter"]["deviceNameTopicExpression"] = SWITCHLEFT
                switch_mappings.append(switch_triple_mapping_left)
                switch_triple_mapping_middle = copy.deepcopy(switch_template)
                switch_triple_mapping_middle["topicFilter"] = switch_template["topicFilter"] + switch + "/+"
                switch_triple_mapping_middle["converter"]["timeseries"][0]["value"] = "${" + STATE_CENTER + "}"
                switch_triple_mapping_middle["converter"]["deviceNameTopicExpression"] = SWITCHCENTER
                switch_mappings.append(switch_triple_mapping_middle)
                switch_triple_mapping_right = copy.deepcopy(switch_template)
                switch_triple_mapping_right["topicFilter"] = switch_template["topicFilter"] + switch + "/+"
                switch_triple_mapping_right["converter"]["timeseries"][0]["value"] = "${" + STATE_RIGHT + "}"
                switch_triple_mapping_right["converter"]["deviceNameTopicExpression"] = SWITCHRIGHT
                switch_mappings.append(switch_triple_mapping_right)
                pass
        self.mappings.extend(switch_mappings)
        print(self.mappings)

    def creat_ir_aircondition_mapping(self):
        self.mappings.append(ZIGBEE2MQTT_IR_AIRCONDITION_MAPPING)

    def creat_aircondition_mapping(self):
        self.mappings.append(ZIGBEE2MQTT_AIRCONDITION_MAPPING)

    def creat_service_rpc(self,type):
        serverside_rpc_dict_template = ZIGBEE2MQTT_SERVERSIDE_RPC
        if type == "ir_serverside_rpc":
            ir_serverside_rpc_dict_template = IR_SENDER_SERVERSIDE_RPC
            # 空调红外码
            ir_func_list = [SET_STATE_OPEN, SET_STATE_CLOSE, SET_WINDSPEED_AUTO, SET_WINDSPEED_ONE, SET_WINDSPEED_TWO,
                            SET_WINDSPEED_THREE, SET_WINDSPEED_FOUR, SET_WINDSPEED_FIVE, SET_WINDSPEED_SIX,
                            SET_WINDSPEED_SEVEN, SET_MODE_AUTO, SET_MODE_COLD, SET_MODE_HOT, SET_MODE_DRY, SET_MODE_FAN,
                            SET_TEM_T17, SET_TEM_T18, SET_TEM_T19, SET_TEM_T20, SET_TEM_T21, SET_TEM_T22, SET_TEM_T23,
                            SET_TEM_T24, SET_TEM_T25, SET_TEM_T26, SET_TEM_T27, SET_TEM_T28, SET_TEM_T29, SET_TEM_T30]
            for ir_func in ir_func_list:
                ir_serverside_rpc_dict = copy.deepcopy(ir_serverside_rpc_dict_template)
                ir_serverside_rpc_dict["methodFilter"] = ir_func
                self._rpc["serverSideRpc"].append(ir_serverside_rpc_dict)
        elif type == "switchs_serverside_rpc":
            if self._switch is not None:
                for switch in self._switch:
                    if switch == "单路开关":
                        for switch_name in self._switch[switch]:
                            sig_serverside_rpc_dict = copy.deepcopy(serverside_rpc_dict_template)
                            sig_serverside_rpc_dict["deviceNameFilter"] = re.findall("(?<=%1\[)(.+?)(?=\]1%)", switch_name)[
                                0]
                            sig_serverside_rpc_dict["requestTopicExpression"] = sig_serverside_rpc_dict[
                                                                                    "requestTopicExpression"] + switch_name + "/set"
                            self._rpc["serverSideRpc"].append(sig_serverside_rpc_dict)
                    elif switch == "双路开关":
                        for switch_name in self._switch[switch]:
                            d1_serverside_rpc_dict = copy.deepcopy(serverside_rpc_dict_template)
                            # 正则表达式"(?<=%1)(.+?)(?=1%)"值
                            d1_serverside_rpc_dict["deviceNameFilter"] = re.findall("(?<=%1\[)(.+?)(?=\]1%)", switch_name)[
                                0]
                            d1_serverside_rpc_dict["requestTopicExpression"] = d1_serverside_rpc_dict[
                                                                                "requestTopicExpression"] + switch_name + "/set"
                            d1_serverside_rpc_dict["valueExpression"] = '{\"state_left\":${params.state}}'
                            self._rpc["serverSideRpc"].append(d1_serverside_rpc_dict)
                            d2_serverside_rpc_dict = copy.deepcopy(serverside_rpc_dict_template)
                            d2_serverside_rpc_dict["deviceNameFilter"] = re.findall("(?<=%2\[)(.+?)(?=\]2%)", switch_name)[
                                0]
                            d2_serverside_rpc_dict["requestTopicExpression"] = d2_serverside_rpc_dict[
                                                                                "requestTopicExpression"] + switch_name + "/set"
                            d2_serverside_rpc_dict["valueExpression"] = '{\"state_right\":${params.state}}'
                            self._rpc["serverSideRpc"].append(d2_serverside_rpc_dict)
                    elif switch == "三路开关":
                        for switch_name in self._switch[switch]:
                            d1_serverside_rpc_dict = copy.deepcopy(serverside_rpc_dict_template)
                            d1_serverside_rpc_dict["deviceNameFilter"] = re.findall("(?<=%1\[)(.+?)(?=\]1%)", switch_name)[
                                0]
                            d1_serverside_rpc_dict["requestTopicExpression"] = d1_serverside_rpc_dict[
                                                                                "requestTopicExpression"] + switch_name + "/set"
                            d1_serverside_rpc_dict["valueExpression"] = '{\"state_left\":${params.state}}'
                            self._rpc["serverSideRpc"].append(d1_serverside_rpc_dict)
                            d2_serverside_rpc_dict = copy.deepcopy(serverside_rpc_dict_template)
                            d2_serverside_rpc_dict["deviceNameFilter"] = re.findall("(?<=%2\[)(.+?)(?=\]2%)", switch_name)[
                                0]
                            d2_serverside_rpc_dict["requestTopicExpression"] = d2_serverside_rpc_dict[
                                                                                "requestTopicExpression"] + switch_name + "/set"
                            d2_serverside_rpc_dict["valueExpression"] = '{\"state_center\":${params.state}}'
                            self._rpc["serverSideRpc"].append(d2_serverside_rpc_dict)
                            d3_serverside_rpc_dict = copy.deepcopy(serverside_rpc_dict_template)
                            d3_serverside_rpc_dict["deviceNameFilter"] = re.findall("(?<=%3\[)(.+?)(?=\]3%)", switch_name)[
                                0]
                            d3_serverside_rpc_dict["requestTopicExpression"] = d3_serverside_rpc_dict[
                                                                                "requestTopicExpression"] + switch_name + "/set"
                            d3_serverside_rpc_dict["valueExpression"] = '{\"state_right\":${params.state}}'
                            self._rpc["serverSideRpc"].append(d3_serverside_rpc_dict)
                        pass
        elif type == "airc_serverside_rpc":
            for temp_dictionary in self._rpc["serverSideRpc"]:
                if AIRCONDITION_SERVERSIDE_RPC == temp_dictionary:
                    self._rpc["serverSideRpc"].remove(temp_dictionary)
            self._rpc["serverSideRpc"].append(AIRCONDITION_SERVERSIDE_RPC)


    def get_names(self):
        for devicename in self.config["devices"].values():
            if devicename.get("friendly_name").split("/")[0] == "空调设备":
                self.names.append(devicename.get("friendly_name").split("/")[1])
            if "开关" in devicename.get("friendly_name").split("/")[0]:
                if devicename.get("friendly_name").split("/")[0] == "单路开关":
                    self.names.append(re.findall("(?<=%1\[)(.+?)(?=\]1%)", devicename.get("friendly_name"))[0])
                elif devicename.get("friendly_name").split("/")[0] == "双路开关":
                    self.names.append(re.findall("(?<=%1\[)(.+?)(?=\]1%)", devicename.get("friendly_name"))[0])
                    self.names.append(re.findall("(?<=%2\[)(.+?)(?=\]2%)", devicename.get("friendly_name"))[0])
                elif devicename.get("friendly_name").split("/")[0] == "三路开关":
                    self.names.append(re.findall("(?<=%1\[)(.+?)(?=\]1%)", devicename.get("friendly_name"))[0])
                    self.names.append(re.findall("(?<=%2\[)(.+?)(?=\]2%)", devicename.get("friendly_name"))[0])
                    self.names.append(re.findall("(?<=%3\[)(.+?)(?=\]3%)", devicename.get("friendly_name"))[0])

        # 打开json文件并写入
        with open(path.join(path.dirname(__file__), "names.json"), "w", encoding='utf-8') as f:
            print(f"数据{self.names}  {f}")
            json.dump(self.names, f, indent=4, ensure_ascii=False)

    
    def start(self):
        self.creat_switch_mapping()
        self.creat_aircondition_mapping()
        #self.creat_ir_aircondition_mapping()
        # self.creat_temprature_mapping()
        self.creat_service_rpc("switchs_serverside_rpc")
        self.creat_service_rpc("airc_serverside_rpc")
        
        while len(self.mappings) > 0:
            element = self.mappings.pop(0)
            for my_dict in self.mqtt["mapping"]:
                if "topicFilter" in my_dict and my_dict["topicFilter"] == element["topicFilter"]:
                    # 如果存在，从列表中删除当前字典
                    self.mqtt["mapping"].remove(my_dict)
            self.mqtt["mapping"].append(element)

        #self.mqtt["serverSideRpc"] = self._rpc["serverSideRpc"]
        while len(self._rpc["serverSideRpc"]) > 0:
            element = self._rpc["serverSideRpc"].pop(0)
            for my_dict in self.mqtt["serverSideRpc"]:
                if my_dict == element:
                    self.mqtt["serverSideRpc"].remove(my_dict)
            self.mqtt["serverSideRpc"].append(element)
        # 规则打印
        # print(json.dumps(self.mqtt, indent=4, ensure_ascii=False))
        # 写入json
        # with open(path.join(path.dirname(__file__), "mqtt.json"), "w", encoding='utf-8') as f:
        #     json.dump(self.mqtt, f, indent=4, ensure_ascii=False)
        return self.mqtt

    def get_mqttjson(self,zigbee_config):
        #初始化self.mqtt
        self.load_config()
        self.config = zigbee_config
        self.start()
        return self.mqtt

if __name__ == "__main__":
    auto_update_mqtt = AutoUpdateMqtt()
    auto_update_mqtt.start()
    pass
